package com.dingup.api.Util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.lang.Objects;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by wancheng on 2018/7/26.
 */
public class JwtTokenUtil {
    /**
     * 密钥
     */
    public final static String tokenName = "Authorization";

    public final static String tokenHead = "Bearer";

    public final static String secret = "aaaaaaaa";

    public final static Long expiraTime = 60 * 60 * 24 * 1000L * 7;

    public static String getUserAccountFromRequset(HttpServletRequest request) {
        String token = getTokenFromRequset(request);
        String userName = getUserAccountFromToken(token);
        return userName;
    }

    public static String getTokenFromRequset(HttpServletRequest request) {
        String token = null;
       token = request.getHeader(tokenName);
        return token;
    }

    public static String createToken(String username, List<String> roles) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("roles", roles);
        map.put("userName", username);
        String token = Jwts.builder()
                .setClaims(map)
                //有效期两小时
                .setExpiration(new Date(System.currentTimeMillis() + expiraTime))
                //采用什么算法是可以自己选择的，不一定非要采用HS512
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();
        return tokenHead + token;
    }

    /**
     * 从数据声明生成令牌
     *
     * @param claims 数据声明
     * @return 令牌
     */
    public static String generateToken(Map<String, Object> claims) {
        Date expirationDate = new Date(System.currentTimeMillis() + expiraTime);
        return Jwts.builder().setClaims(claims).setExpiration(expirationDate).signWith(SignatureAlgorithm.HS512, secret).compact();
    }

    /**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    public static Claims getClaimsFromToken(String token) {
        token = token.replace(tokenHead, "");
        Claims claims;
        try {
            claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
        } catch (Exception e) {
            claims = null;
        }
        return claims;
    }

    /**
     * 从令牌中获取用户名
     *
     * @param token 令牌
     * @return 用户名
     */
    public static String getUserAccountFromToken(String token) {
        String username;
        try {
            Claims claims = getClaimsFromToken(token);
            username = claims.get("userName").toString();
        } catch (Exception e) {
            username = null;
        }
        return username;
    }

    public static List<String> getRolesFromToken(String token) {
        String username;
        List<String> roles = null;
        try {
            Claims claims = getClaimsFromToken(token.replace(tokenHead, ""));
            roles = (List<String>) claims.get("roles");
        } catch (Exception e) {
            username = null;
        }
        return roles;
    }
    public static List<String> getRolesFromRequest(HttpServletRequest request) {
        String token = getTokenFromRequset(request);
        List<String> roles = null;
        try {
            Claims claims = getClaimsFromToken(token.replace(tokenHead, ""));
            roles = (List<String>) claims.get("roles");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return roles;
    }
    /**
     * 判断令牌是否过期
     *
     * @param token 令牌
     * @return 是否过期
     */
    public static Boolean isTokenExpired(String token) {
        token = token.replace(tokenHead, "");
        try {
            Claims claims = getClaimsFromToken(token);
            Date expiration = claims.getExpiration();
            return expiration.before(new Date());
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 刷新令牌
     *
     * @param token 原令牌
     * @return 新令牌
     */
    public static String refreshToken(String token) {
        token = token.replace(tokenHead, "");
        String refreshedToken;
        try {
            Claims claims = getClaimsFromToken(token);
            claims.put("created", new Date());
            refreshedToken = tokenHead + generateToken(claims);
        } catch (Exception e) {
            refreshedToken = null;
        }
        return refreshedToken;
    }

    public static void main(String[] ar){
        String token = "BearereyJhbGciOiJIUzUxMiJ9.eyJyb2xlcyI6WyJpc0VkaXRBdXRoUGVybWlzc2lvbiIsImlzQXV0aFBhZ2VQZXJtaXNzaW9uIiwiaXNVc2VyUGFnZVBlcm1pc3Npb24iLCJpc0RlbFVzZXJBdXRoUGVybWlzc2lvbiIsImlzRGluZ1Blcm1pc3Npb24iLCJpc1VzZXJNYW5hZ2VBdXRoUGVybWlzc2lvbiIsImlzTWFuYWdlQXV0aFBlcm1pc3Npb24iLCJpc1Blb3BsZVBhZ2VQZXJtaXNzaW9uIl0sInVzZXJOYW1lIjoi5p2O55Gc5aiHIiwiZXhwIjoxNTM0NDE4NzM5fQ.IUNXeuzkXDk0NRRe0UAU0lHwGzqhoDVRo1IKpMbT7ZzDMsKd_zFr633jXOYkuurThJCe7e6u63ei5dezibXiNA";
        String account = getUserAccountFromToken(token);
        System.out.print(account);
    }
}
